#include <stdio.h>
#include <string.h>
#include <stdlib.h>

//定义链表节点存储数据的个数
#define LINK_NODE_SIZE 3

//定义字符串存储用到的链表
typedef struct Link {
    //数据域
    char data[LINK_NODE_SIZE];
    //节点指针
    struct Link *next;
} link;

void fixed_length_order_store_string() {
    char a[20] = "www.baidu.com";
    printf("定长存储的值是: \"%s\" ,长度是: %lu \n", a, strlen(a));
}

void heap_memory_store_string() {
    char *s1 = NULL;
    char *s2 = NULL;
    s1 = (char *) malloc(sizeof(char) * 20);
    s2 = (char *) malloc(sizeof(char) * 20);
    s1 = strcpy(s1, "https://www.bai");
    s2 = strcpy(s2, "du.com/index.php");
    int s1Len = strlen(s1);
    int s2Len = strlen(s2);
    if (s1Len < (s2Len + s1Len)) {
        s1 = (char *) realloc(s1, sizeof(char) * (s1Len + 1 + s2Len));
    }
    for (int i = s1Len; i < s1Len + s2Len; ++i) {
        s1[i] = s2[i - s1Len];
    }

    //串的默认尾加 \0
    s1[s1Len + s2Len] = '\0';
    printf("%s", s1);
    free(s1);
    free(s2);
}

link *block_store_string(link *head, char *data) {
    //1.计算出需要的节点数量
    //2.生成节点
    //3.把字符串塞进节点中

    int data_len = strlen(data);
    int node_num = data_len / LINK_NODE_SIZE;
    if (data_len % LINK_NODE_SIZE) {
        node_num++;
    }

    //生成首元节点，并把头指针指向它
    head = (link *) malloc(sizeof(link));
    head->next = NULL;
    link *temp = head;

    for (int i = 0; i < node_num; ++i) {
        int j = 0;
        for (; j < LINK_NODE_SIZE; ++j) {
            if (i * LINK_NODE_SIZE + j < data_len) {
                temp->data[j] = data[i * LINK_NODE_SIZE + j];
            } else {
                temp->data[j] =  '#';
            }
        }

        if (i * LINK_NODE_SIZE + j < data_len) {
            link *new_node = (link *) malloc(sizeof(link));
            new_node->next = NULL;
            temp->next = new_node;
            temp = new_node;
        }
    }

    return head;
}


//打印链表
void display_link(link *head) {
    link *temp = head;
    while (temp) {
        for (int i = 0; i < LINK_NODE_SIZE; ++i) {
            printf("%c", temp->data[i]);
        }
        temp = temp->next;
    }
}

int main() {
    printf("定长存储字符串: \n");
    fixed_length_order_store_string();
    printf("分配堆内存来存储字符串: \n");
    heap_memory_store_string();
    printf("\n 串的块链存储: \n");
    link *head = NULL;
    // 为什么当字符串无法填满节点，填充 "#" 会显示6 ？ 原来是单双引号的问题
    head = block_store_string(head, "My name is qiang.");
    display_link(head);
    return 0;
}
